function Tests = modelExogenizeTest()
Tests = functiontests(localfunctions);
end
%#ok<*DEFNU>


%**************************************************************************


function setupOnce(This)
m = model('3eq.Model','linear=',true);
m = solve(m);
m = sstate(m);
This.TestData.Model = m;

n = model('n3eq.Model');
n = sstate(n,'display=','none');
n = solve(n);
This.TestData.NonlModel = n;

eqtn = findeqtn(n,'Phillips');
This.TestData.Phillips = eqtn;
end % setupOnce( )


%**************************************************************************


function testExogenizeAnt(This)
m = This.TestData.Model;
d = sstatedb(m,1:20,'randomShocks=',true);
s = simulate(m,d,1:20);
p = plan(m,1:20);
p = exogenize(p,'pie,y,r',1:20);
p = endogenize(p,'epie,ey,er',1:20);
w = simulate(m,s,1:20,'plan=',p);
assertEqual(This,s.y(:),w.y(:));
assertEqual(This,s.pie(:),w.pie(:));
assertEqual(This,s.r(:),w.r(:));
end % testExogenizeAnt( )


%**************************************************************************


function testExogenizeUnant(This)
m = This.TestData.Model;
d = sstatedb(m,1:20,'randomShocks=',true);
s = simulate(m,d,1:20,'anticipate=',false);
p = plan(m,1:20);
p = exogenize(p,'pie,y,r',1:20);
p = endogenize(p,'epie,ey,er',1:20);
w = simulate(m,s,1:20,'plan=',p,'anticipate=',false);
assertEqual(This,s.y(:),w.y(:));
assertEqual(This,s.pie(:),w.pie(:));
assertEqual(This,s.r(:),w.r(:));
end % testExogenizeUnant( )

%**************************************************************************


function testExogenizeNonlin(This)
n = This.TestData.NonlModel;
tol = 1e-9;
nSim = 20;
nNonl = 25;
d = sstatedb(n,1:nSim);
d = shockdb(n,d,11:nSim,'randFunc=',@randn);
phillips = This.TestData.Phillips;
p = plan(n,1:20);
p = exogenize(p,'pie,Y,r',11:nSim);
p = endogenize(p,'epie,ey,er',11:nSim);
list = get(n,'xList');
for ant = [true,false]
    for maxNumelJv = [0,Inf]
        doTest( );
    end
end

return

    

    function doTest( )
        s = simulate(n,d,1:nSim,'anticipate=',ant, ...
            'method=','selective','maxIter=',10000,'display=',0, ...
            'tolerance=',1e-12,'lambda=',1,'solver=',@qad, ...
            'nonlinper=',nNonl, ...
            'maxNumelJv=',maxNumelJv);
        z = dbeval(s,phillips);
        assertLessThan(This,abs(z),tol);
        assertEqual(This,s.Y(1:nSim),exp(s.y(1:nSim)/100),'AbsTol',tol);
        d1 = s;
        d1.epie(:) = 0;
        d1.er(:) = 0;
        d1.ey(:) = 0;
        w = simulate(n,d1,1:nSim,'anticipate=',ant,'plan=',p, ...
            'method=','selective','maxIter=',10000,'display=',0, ...
            'tolerance=',1e-12,'nonlinper=',25, ...
            'maxNumelJv=',maxNumelJv);
        for i = 1 : length(list)
            name = list{i};
            assertEqual(This,s.(name)(1:nSim),w.(name)(1:nSim),'AbsTol',tol);
        end
        c = simulate(n,w,1:nSim,'anticipate=',ant,'contributions=',true, ...
            'method=','selective','maxIter=',10000,'display=',0, ...
            'tolerance=',1e-12,'nonlinper=',25, ...
            'maxNumelJv=',maxNumelJv);
        for i = 1 : length(list)
            name = list{i};
            if islog(n,name)
                aggregFn = @prod;
            else
                aggregFn = @sum;
            end
            cc = aggregFn(c.(name),2);
            assertEqual(This,s.(name)(1:nSim),cc(1:nSim),'AbsTol',tol);
        end        
    end % doTest( )



end % testExogenizeNonlin( )

